﻿/*
 * 
 * Responsabilidade:
 * Fornecer estruturas de dados para guardar configurações do sistema
 * Forneçer métodos para manipular e aplicar estas estruturas
 * Forneçer mecanismos para intercambio com a registry
 * 
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using Microsoft.Win32;
using System.Windows.Forms;
using System.Globalization;


namespace J_Controle
{
    public class ConfigPorta
    {
        public string Nome;
        public const int ReceivedBytesThreshold = 1;

        private int _bps;

        public int BpsVal
        {
            get { return _bps; }
            set { _bps = value; }
        }
        public string BpsText
        {
            get { return _bps.ToString(); }
            set { _bps = int.Parse(value); }
        }

        private StopBits _Stop;
        public StopBits StopVal
        {
            get { return _Stop; }
            set { _Stop = value; }
        }
        public string StopText
        {
            get { return _Stop.ToString(); }
            set { _Stop = (StopBits)Enum.Parse(typeof(StopBits), value, true); }
        }

        private Parity _Pty;
        public Parity PtyVal
        {
            get { return _Pty; }
            set { _Pty = value; }
        }
        public String PtyText
        {
            get { return _Pty.ToString(); }
            set { _Pty = (Parity)Enum.Parse(typeof(Parity), value, true); }
        }

        private byte _ParityReplace;
        public byte ParityReplaceVal
        {
            get { return _ParityReplace; }
            set { _ParityReplace = value; }
        }
        public string ParityReplaceText
        {
            get { return String.Format("{0:X2}",_ParityReplace); }
            set 
            {
                if (!Byte.TryParse(value, NumberStyles.HexNumber, null, out _ParityReplace))
                {
                    MessageBox.Show(value + " " + "não é um hexadecimal legítimo.");
                    return;
                }
            }
        }

        public ConfigPorta()
        {
            Nome = "COM1";
            _bps = 9600;
            _Pty = Parity.Even;
            _Stop = StopBits.Two;
            _ParityReplace = 0xFE;
        }
        public ConfigPorta(SerialPort prmPorta)
        {
            // lendo os parâmetros da configuração
            if (prmPorta == null) throw new ArgumentNullException("Constructor ConfigPorta não aceita prmPorta == null.");
        }
        public void Configurar(SerialPort prmPorta)
        {
            // aplicando a configuração à porta
            if (prmPorta == null) throw new ArgumentNullException("ConfigPorta.Configurar não aceita prmPorta == null.");
        }
    }

    public struct ConfigHW
    {
        public string TipoProcessador;
        public string VersaoProcessador;
        public string IdProc;

        public string TipoCircuitoMonitoramento;
        public string VersaoCircuitoMonitoramento;
        public string IdCirmon;
    }


    public static class Configuracao
    {
        // ============================
        //
        // Propriedades ofereçendos valores padrão

        public static ConfigHW ConfigHwPadrao
        {
            get
            {
                ConfigHW ch = new ConfigHW();
                ch.TipoProcessador = "XYSC_1";
                ch.VersaoProcessador = "V2";
                ch.IdProc = ch.TipoProcessador + "_" + ch.VersaoProcessador;
                ch.TipoCircuitoMonitoramento = "ProcOp";
                ch.VersaoCircuitoMonitoramento = "3_3";
                ch.IdCirmon = ch.TipoCircuitoMonitoramento + "_" + ch.VersaoCircuitoMonitoramento;
                return ch;
            }
        }


        // ===========================================
        //
        // Métodos de acecsso ao registry

        public static void IniRegistry()
        {
            RegistryKey rkUser = null;
            RegistryKey rkJSoft = null;
            RegistryKey rkJC = null;

            try
            {
                rkUser = Registry.CurrentUser;

                // inicializar JSoft se necessario
                rkJSoft = rkUser.OpenSubKey("JSoft", true);
                if (rkJSoft == null) rkJSoft = rkUser.CreateSubKey("JSoft", RegistryKeyPermissionCheck.ReadWriteSubTree);


                // inicializar J-Controle se necessário
                rkJC = rkJSoft.OpenSubKey("J-Controle", RegistryKeyPermissionCheck.ReadWriteSubTree);
                if (rkJC == null)
                {
                    ConfigPorta cp = new ConfigPorta();  // com valores default
                    rkJC = rkJSoft.CreateSubKey("J-Controle", RegistryKeyPermissionCheck.ReadWriteSubTree);
                    rkJC.SetValue("PortaSerialNome", cp.Nome);
                    rkJC.SetValue("PortaSerialBps", cp.BpsText);
                    rkJC.SetValue("PortaSerialParity", cp.PtyText);
                    rkJC.SetValue("PortaSerialStop", cp.StopText);

                    rkJC.SetValue("CircuitoMonitoramento", ConfigHwPadrao.IdCirmon);
                    rkJC.SetValue("Processador", ConfigHwPadrao.IdProc);
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "Excexção em IniRegistry");
            }
            finally
            {
                if (rkJC != null) rkJC.Close();
                if (rkJSoft != null) rkJSoft.Close();
                if (rkUser != null) rkUser.Close();
            }



        }
        public static void GravarRegistry(ConfigPorta prmPorta, ConfigHW prmHW)
        {
            // Salvar configurações do aplicativo no registry
            RegistryKey rkUser = null;
            RegistryKey rkJSoft = null;
            RegistryKey rkJC = null;

            try
            {
                rkUser = Registry.CurrentUser;

                // inicializar JSoft se necessario
                rkJSoft = rkUser.OpenSubKey("JSoft", true);
                if (rkJSoft == null) throw new ApplicationException("JSoft falta no registry.");

                rkJC = rkJSoft.OpenSubKey("J-Controle", RegistryKeyPermissionCheck.ReadWriteSubTree);
                if (rkJC == null) throw new ApplicationException("J-Controle falta no registry.");

                rkJC.SetValue("PortaSerialNome", prmPorta.Nome);
                rkJC.SetValue("PortaSerialBps", prmPorta.BpsText);
                rkJC.SetValue("PortaSerialStop", prmPorta.StopText);
                rkJC.SetValue("PortaSerialParity", prmPorta.PtyText);

                rkJC.SetValue("CircuitoMonitoramento", prmHW.IdCirmon);
                rkJC.SetValue("Processador", prmHW.IdProc);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "Excexção em GravarRegistry");
            }
            finally
            {
                if (rkJC != null) rkJC.Close();
                if (rkJSoft != null) rkJSoft.Close();
                if (rkUser != null) rkUser.Close();
            }
        }
        public static void LerRegistry(out ConfigPorta CnfPort, out ConfigHW CnfHW) 
        {
            // Ler configurações do aplicativo da registry
            // Devolve os valores de chaves em parâmetros out.
            // Joga excexçaõ em caso de problemas de leitura de chaves do registry.

            ConfigPorta cp = new ConfigPorta();
            ConfigHW ch = new ConfigHW();

            RegistryKey rkUser = null;
            RegistryKey rkJSoft = null;
            RegistryKey rkJC = null;

            CnfPort = cp;  // dummy para satizfazer o compilador
            CnfHW = ch;

            try
            {
                rkUser = Registry.CurrentUser;

                rkJSoft = rkUser.OpenSubKey("JSoft", true);
                if (rkJSoft == null) throw new ApplicationException("JSoft falta no registry.");

                rkJC = rkJSoft.OpenSubKey("J-Controle", true);
                if (rkJC == null) throw new ApplicationException("J-Controle falta no registry.");

                cp.Nome = (string)rkJC.GetValue("PortaSerialNome");
                cp.BpsText = (string)rkJC.GetValue("PortaSerialBps");
                cp.PtyText = (string)rkJC.GetValue("PortaSerialParity");
                cp.StopText = (string)rkJC.GetValue("PortaSerialStop");
                CnfPort = cp;

                //ch.IdCirmon = (string)rkJC.GetValue("CircuitoMonitoramento");
                //ch.IdProc = (string)rkJC.GetValue("Processador");
                ch.IdCirmon = "ProcOP_3_3";
                ch.IdProc = "XYSC1_V2";
                CnfHW = ch;

                return;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "Excexção em LerRegistry");
            }
            finally
            {
                if (rkJC != null) rkJC.Close();
                if (rkJSoft != null) rkJSoft.Close();
                if (rkUser != null) rkUser.Close();
            }

        }

    }
}
